5. Manipulação de Dados

1 Diretório

2 Pacotes e dados

library(rio)
library(tidyverse)
library(metan)
# set_wd_here("data")

3 Girar

Geralmente, os dados são organizados para facilitar algum uso que não seja a análise. Por exemplo, os dados geralmente são organizados para facilitar ao máximo a coleta. Isso significa que, para a maioria das análises, os dados não estarão em um formato tidy e você precisará fazer algumas transformações morfológicas. O primeiro passo é sempre descobrir quais são as variáveis a serem transformadas. O segundo passo é resolver um dos dois problemas mais comuns:

  • Uma variável pode estar espalhada por várias colunas.
  • Uma observação pode estar espalhada por várias linhas.

Note o exemplo abaixo.

Exemplo de dados em um formato “wide”

No caso acima, a altura de planta de plantas de feijão foi mensurada em cinco plantas de cada bloco de três diferentes tratamentos. Então, cada tratamento conterá 15 valores. Note que as medições de cada planta estão dispostas em cinco diferentes colunas (P1 a P5). Então, a variável altura de planta está espalhada por várias colunas. Para corrigir esse problema e o problema de uma observação estar espalhada por várias linhas, utilizaremos duas das mais importantes do pacote tidyr: pivot_longer() e pivot_wider().

3.1 Longer

(df_wide <- import("examples_data.xlsx", sheet = "feijao"))
  UE BLOCO ADUBACAO   P1   P2   P3   P4   P5
1  1     1       AO 16.0 17.0 19.0 15.0 17.0
2  2     1       AQ 21.5 17.0 13.5 14.0 15.0
3  3     1       SA 13.0 16.5 11.5 14.5 12.5
4  4     2       AQ 15.0 14.0 13.0 16.0 16.0
5  5     2       AO 14.0 17.0 18.0 16.0 14.0
6  6     2       SA 15.0 14.0 16.0 16.0 13.0
7  7     3       AO 17.0 17.0 11.0 16.0 15.0
8  8     3       SA 17.0 16.0 14.0 17.0 12.0
9  9     3       AQ 16.0 17.0 14.0 16.0 12.0

Para organizar um conjunto de dados como esse, precisamos dinamizar as colunas problemáticas em duas novas colunas (variável e valor) utilizando a função pivot_longer().

Exemplo da função pivot_longer(). Fonte: https://github.com/rstudio/cheatsheets/blob/main/tidyr.pdf

Para realizar essa operação, precisamos de três parâmetros (além do conjunto de dados)

  • cols: o conjunto de colunas cujos nomes são valores, não variáveis. Neste exemplo, essas são as colunas P1, P2, P3, P4 e P5.
  • names_to: O nome da variável para a qual mover os nomes das colunas. Aqui será "PLANTA".
  • values_to: O nome da variável para a qual mover os valores da coluna. Aqui será "ALTURA".
long <- 
  pivot_longer(df_wide,
               cols = P1:P5,
               names_to = "PLANTA",
               values_to = "AP")
long
# A tibble: 45 × 5
      UE BLOCO ADUBACAO PLANTA    AP
   <dbl> <dbl> <chr>    <chr>  <dbl>
 1     1     1 AO       P1      16  
 2     1     1 AO       P2      17  
 3     1     1 AO       P3      19  
 4     1     1 AO       P4      15  
 5     1     1 AO       P5      17  
 6     2     1 AQ       P1      21.5
 7     2     1 AQ       P2      17  
 8     2     1 AQ       P3      13.5
 9     2     1 AQ       P4      14  
10     2     1 AQ       P5      15  
# ℹ 35 more rows

Após a modificação, as colunas são descartadas e obtemos as colunas de planta e altura. Assim, vemos que pivot_longer() torna os conjuntos de dados mais longos aumentando o número de linhas e diminuindo o número de colunas.

3.2 Wider

Uma outra forma comum de dados que não seguem o formato tidy é quando observações estão espalhadas por várias linhas. Observe os dados abaixo.

(dflong <- import("examples_data.xlsx", sheet = "df2"))
   HIBRIDO BLOCO  VARIAVEL VALOR
1       H1     I ALT_PLANT 3.002
2       H1     I   ALT_ESP 1.878
3       H1    II ALT_PLANT 2.974
4       H1    II   ALT_ESP 1.834
5       H1   III ALT_PLANT 2.814
6       H1   III   ALT_ESP 1.674
7       H2     I ALT_PLANT 2.104
8       H2     I   ALT_ESP 0.910
9       H2    II ALT_PLANT 2.120
10      H2    II   ALT_ESP 1.034
11      H2   III ALT_PLANT 1.924
12      H2   III   ALT_ESP 1.018
13      H3     I ALT_PLANT 2.132
14      H3     I   ALT_ESP 1.052
15      H3    II ALT_PLANT 2.126
16      H3    II   ALT_ESP 1.012
17      H3   III ALT_PLANT 2.182
18      H3   III   ALT_ESP 0.992

Neste caso, duas variáveis (ALT_PLANT e ALT_ESP) estão espalhadas pelas linhas. Para lidar com esse problema, utilizamos a função pivot_wider() que é o oposto de pivot_longer().

Exemplo da função pivot_longer(). Fonte: https://github.com/rstudio/cheatsheets/blob/main/tidyr.pdf

Exemplo da função pivot_wider(). Fonte: https://github.com/rstudio/cheatsheets/blob/main/tidyr.pdf

Para arrumarmos os dados em dflong utilizamos pivot_wider() de maneira similar à pivot_longer(). Desta vez, no entanto, precisamos apenas de dois parâmetros:

  • names_from: A coluna da qual obter nomes de variáveis. Aqui, é "VARIAVEL".
  • values_from: A coluna da qual obter valores. Aqui é "VALOR".
wider <- 
   dflong |> 
     pivot_wider(names_from = VARIAVEL,
                 values_from = VALOR)
wider
# A tibble: 9 × 4
  HIBRIDO BLOCO ALT_PLANT ALT_ESP
  <chr>   <chr>     <dbl>   <dbl>
1 H1      I          3.00   1.88 
2 H1      II         2.97   1.83 
3 H1      III        2.81   1.67 
4 H2      I          2.10   0.91 
5 H2      II         2.12   1.03 
6 H2      III        1.92   1.02 
7 H3      I          2.13   1.05 
8 H3      II         2.13   1.01 
9 H3      III        2.18   0.992

4 Separar

Até agora você aprendeu como realizar operações morfológicas para transformar dados em de formato wide para long e vice-versa. O seguinte conjunto de dados tem um problema diferente:

(ex_separate <- import("examples_data.xlsx", sheet = "df5"))
  HIBRIDO BLOCO ALT_PLANT ALT_ESP       RELACAO
1      H1     I     3.002   1.878 1.878 / 3.002
2      H1    II     2.974   1.834 1.834 / 2.974
3      H1   III     2.814   1.674 1.674 / 2.814
4      H2     I     2.104   0.910  0.91 / 2.104
5      H2    II     2.120   1.034  1.034 / 2.12
6      H2   III     1.924   1.018 1.018 / 1.924
7      H3     I     2.132   1.052 1.052 / 2.132
8      H3    II     2.126   1.012 1.012 / 2.126
9      H3   III     2.182   0.992 0.992 / 2.182

Observe que a coluna temos uma coluna (RELACAO) contém duas variáveis (ALT_ESP e ALT_PLANT). Para corrigir esse problema, precisaremos da função separate().

Exemplo da função pivot_longer(). Fonte: https://github.com/rstudio/cheatsheets/blob/main/tidyr.pdf

Exemplo da função separate(). Fonte: https://github.com/rstudio/cheatsheets/blob/main/tidyr.pdf

Por padrão, separate() dividirá valores onde quer que veja um caractere não alfanumérico. Você também pode explicitar um separador para as colunas. Note o que acontece abaixo.

# por padrão, separa no primeiro caractere alfanumérico (.)
ex_separate |> 
  separate_wider_delim(RELACAO, names = c("AESP", "APLA"), delim = "/")
# A tibble: 9 × 6
  HIBRIDO BLOCO ALT_PLANT ALT_ESP AESP     APLA    
  <chr>   <chr>     <dbl>   <dbl> <chr>    <chr>   
1 H1      I          3.00   1.88  "1.878 " " 3.002"
2 H1      II         2.97   1.83  "1.834 " " 2.974"
3 H1      III        2.81   1.67  "1.674 " " 2.814"
4 H2      I          2.10   0.91  "0.91 "  " 2.104"
5 H2      II         2.12   1.03  "1.034 " " 2.12" 
6 H2      III        1.92   1.02  "1.018 " " 1.924"
7 H3      I          2.13   1.05  "1.052 " " 2.132"
8 H3      II         2.13   1.01  "1.012 " " 2.126"
9 H3      III        2.18   0.992 "0.992 " " 2.182"

5 Concatenar

Quem trabalha com excel muito provavelmente já utilizou a função =CONCAT, que concatena valores de múltiplas colunas em uma única coluna. Aqui, a função unite(), pode ser utilizada para este fim. Ela é o inverso da separate().

Exemplo da função pivot_longer(). Fonte: https://github.com/rstudio/cheatsheets/blob/main/tidyr.pdf

Exemplo da função unite(). Fonte: https://github.com/rstudio/cheatsheets/blob/main/tidyr.pdf

Vamos considerar que queiramos unir as colunas HIBRIDO e BLOCO do conjunto dflong em uma única coluna, chamada NÍVEL. Esta união é dada por

dflong |> 
  unite("NIVEL", HIBRIDO:BLOCO) |> 
  head()
   NIVEL  VARIAVEL VALOR
1   H1_I ALT_PLANT 3.002
2   H1_I   ALT_ESP 1.878
3  H1_II ALT_PLANT 2.974
4  H1_II   ALT_ESP 1.834
5 H1_III ALT_PLANT 2.814
6 H1_III   ALT_ESP 1.674

6 Renomear (Homework)

Algumas vezes necessitamos renomear as variáveis em nosso conjunto de dados. Seria trabalhoso mudar o nome da coluna nos dados externos e importa-los novamente. Vamos considerar os dados em long e renomear a coluna UE > PARCELA e BLOCO > REP. Aqui, algumas alternativas são apresentadas.

6.1 R base

long1 <- long
names(long1)[c(1, 2)] <- c("PARCELA", "REP")
names(long1)
[1] "PARCELA"  "REP"      "ADUBACAO" "PLANTA"   "AP"      

6.2 dplyr rename()

A função rename() do pacote dplyr altera os nomes de variáveis individuais usando a sintaxe nome_novo = nome_antigo.

rename(long,
       PARCELA = UE,
       REP = BLOCO) |> 
  names()
[1] "PARCELA"  "REP"      "ADUBACAO" "PLANTA"   "AP"      

6.3 dplyr rename_with()

Uma outra alternativa é rename_with(), que renomeia colunas usando uma função.

rename_with(long, tolower) |> names()
[1] "ue"       "bloco"    "adubacao" "planta"   "ap"      

6.4 metan add_prefix() e add_suffix()

Prefixos e sufixos são extremamente úteis na manipulação de dados, pois permitem que select helpers possam ser utilizados na seleção de variáveis, que será visto no próximo tópico. Aqui, vamos ver como prefixos e sufixos podem ser adicionados à nomes das variáveis.

long |> 
  add_prefix(UE:PLANTA, prefix = "Fct") |> 
  names()
[1] "Fct_UE"       "Fct_BLOCO"    "Fct_ADUBACAO" "Fct_PLANTA"   "AP"          
# utilizando select helper
long |> 
  add_suffix(starts_with("A"), suffix = "a") |> 
  select(contains("_a")) |> 
  names()
[1] "ADUBACAO_a" "AP_a"      

7 Juntar

É raro que uma análise de dados envolva apenas uma única tabela de dados. Na prática, diversas tabela podem existir e ferramentas flexíveis para combiná-las são necessárias. No dplyr, existem uma família de funções do tipo *_join(x, y) que podem ser utilizadas para unir colunas de y a x, combinando linhas com base nas chaves:

7.1 Junções com mutação

Se uma linha em x corresponder a várias linhas em y, todas as linhas em y serão retornadas uma vez para cada linha correspondente em x.

Fonte: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf

Vamos à um exemplo prático!

(df1 <- import("joins.xlsx", sheet = "left"))
                  author cntry
1      Graetzel, Michael   che
2        Wang, Zhong Lin   chn
3     Willett, Walter C.   usa
4          Kresse, Georg   aut
5     Kessler, Ronald C.   usa
6          Friston, Karl   gbr
7     Altman, Douglas G.   gbr
8       McEwen, Bruce S.   usa
9  Whitesides, George M.   usa
10        Witten, Edward   usa
11      Barnes, Peter J.   gbr
12       Perdew, John P.   usa
13      Halliwell, Barry   sgp
14          Ridker, Paul   usa
15        Karin, Michael   usa
16       Bandura, Albert   usa
17     Semenza, Gregg L.   usa
18          Yusuf, Salim   can
19          Libby, Peter   usa
20        Langer, Robert   usa
(df2 <- import("joins.xlsx", sheet = "right"))
                  author                                 inst_name rank (ns)
1          Akira, Shizuo                          Osaka University        25
2         Folkman, Judah                    Harvard Medical School        24
3          Friston, Karl                 University College London         6
4    Goodenough, John B.         The University of Texas at Austin        36
5      Graetzel, Michael  École Polytechnique Fédérale de Lausanne         1
6         Grimme, Stefan                          Universität Bonn        27
7       Halliwell, Barry          National University of Singapore        13
8           Hu, Frank B.                    Harvard Medical School        26
9   Ioannidis, John P.A.                       Stanford University        22
10       Jain, Rakesh K.            Massachusetts General Hospital        29
11        Karin, Michael           UC San Diego School of Medicine        15
12    Kessler, Ronald C.                    Harvard Medical School         5
13         Kresse, Georg                          Universität Wien         4
14        Kroemer, Guido                       Sorbonne Université        34
15        Langer, Robert     Massachusetts Institute of Technology        20
16       Trost, Barry M.                       Stanford University        37
17          Wang, Joseph       University of California, San Diego        35
18       Wang, Zhong Lin               Chinese Academy of Sciences         2
19 Whitesides, George M.      Harvard Faculty of Arts and Sciences         9
20    Willett, Walter C. Harvard T.H. Chan School of Public Health         3
21        Witten, Edward              Institute for Advanced Study        10
22          Yusuf, Salim                       McMaster University        18
23       Zadeh, Lotfi A.        University of California, Berkeley        28
   nc9623 (ns)
1       273403
2       130951
3       188600
4       122468
5       365234
6       125623
7       113708
8       222570
9       242211
10      145488
11      208736
12      267255
13      297085
14      241541
15      243723
16       80092
17      102177
18      279327
19      244615
20      346654
21      101514
22      254242
23      126012
# todas as linhas de df1
df1 |> left_join(df2)
Joining with `by = join_by(author)`
                  author cntry                                 inst_name
1      Graetzel, Michael   che  École Polytechnique Fédérale de Lausanne
2        Wang, Zhong Lin   chn               Chinese Academy of Sciences
3     Willett, Walter C.   usa Harvard T.H. Chan School of Public Health
4          Kresse, Georg   aut                          Universität Wien
5     Kessler, Ronald C.   usa                    Harvard Medical School
6          Friston, Karl   gbr                 University College London
7     Altman, Douglas G.   gbr                                      <NA>
8       McEwen, Bruce S.   usa                                      <NA>
9  Whitesides, George M.   usa      Harvard Faculty of Arts and Sciences
10        Witten, Edward   usa              Institute for Advanced Study
11      Barnes, Peter J.   gbr                                      <NA>
12       Perdew, John P.   usa                                      <NA>
13      Halliwell, Barry   sgp          National University of Singapore
14          Ridker, Paul   usa                                      <NA>
15        Karin, Michael   usa           UC San Diego School of Medicine
16       Bandura, Albert   usa                                      <NA>
17     Semenza, Gregg L.   usa                                      <NA>
18          Yusuf, Salim   can                       McMaster University
19          Libby, Peter   usa                                      <NA>
20        Langer, Robert   usa     Massachusetts Institute of Technology
   rank (ns) nc9623 (ns)
1          1      365234
2          2      279327
3          3      346654
4          4      297085
5          5      267255
6          6      188600
7         NA          NA
8         NA          NA
9          9      244615
10        10      101514
11        NA          NA
12        NA          NA
13        13      113708
14        NA          NA
15        15      208736
16        NA          NA
17        NA          NA
18        18      254242
19        NA          NA
20        20      243723
# todas as linhas de df2
df1 |> right_join(df2)
Joining with `by = join_by(author)`
                  author cntry                                 inst_name
1      Graetzel, Michael   che  École Polytechnique Fédérale de Lausanne
2        Wang, Zhong Lin   chn               Chinese Academy of Sciences
3     Willett, Walter C.   usa Harvard T.H. Chan School of Public Health
4          Kresse, Georg   aut                          Universität Wien
5     Kessler, Ronald C.   usa                    Harvard Medical School
6          Friston, Karl   gbr                 University College London
7  Whitesides, George M.   usa      Harvard Faculty of Arts and Sciences
8         Witten, Edward   usa              Institute for Advanced Study
9       Halliwell, Barry   sgp          National University of Singapore
10        Karin, Michael   usa           UC San Diego School of Medicine
11          Yusuf, Salim   can                       McMaster University
12        Langer, Robert   usa     Massachusetts Institute of Technology
13         Akira, Shizuo  <NA>                          Osaka University
14        Folkman, Judah  <NA>                    Harvard Medical School
15   Goodenough, John B.  <NA>         The University of Texas at Austin
16        Grimme, Stefan  <NA>                          Universität Bonn
17          Hu, Frank B.  <NA>                    Harvard Medical School
18  Ioannidis, John P.A.  <NA>                       Stanford University
19       Jain, Rakesh K.  <NA>            Massachusetts General Hospital
20        Kroemer, Guido  <NA>                       Sorbonne Université
21       Trost, Barry M.  <NA>                       Stanford University
22          Wang, Joseph  <NA>       University of California, San Diego
23       Zadeh, Lotfi A.  <NA>        University of California, Berkeley
   rank (ns) nc9623 (ns)
1          1      365234
2          2      279327
3          3      346654
4          4      297085
5          5      267255
6          6      188600
7          9      244615
8         10      101514
9         13      113708
10        15      208736
11        18      254242
12        20      243723
13        25      273403
14        24      130951
15        36      122468
16        27      125623
17        26      222570
18        22      242211
19        29      145488
20        34      241541
21        37       80092
22        35      102177
23        28      126012
# todas as linhas de df1 e df2
df1 |> inner_join(df2)
Joining with `by = join_by(author)`
                  author cntry                                 inst_name
1      Graetzel, Michael   che  École Polytechnique Fédérale de Lausanne
2        Wang, Zhong Lin   chn               Chinese Academy of Sciences
3     Willett, Walter C.   usa Harvard T.H. Chan School of Public Health
4          Kresse, Georg   aut                          Universität Wien
5     Kessler, Ronald C.   usa                    Harvard Medical School
6          Friston, Karl   gbr                 University College London
7  Whitesides, George M.   usa      Harvard Faculty of Arts and Sciences
8         Witten, Edward   usa              Institute for Advanced Study
9       Halliwell, Barry   sgp          National University of Singapore
10        Karin, Michael   usa           UC San Diego School of Medicine
11          Yusuf, Salim   can                       McMaster University
12        Langer, Robert   usa     Massachusetts Institute of Technology
   rank (ns) nc9623 (ns)
1          1      365234
2          2      279327
3          3      346654
4          4      297085
5          5      267255
6          6      188600
7          9      244615
8         10      101514
9         13      113708
10        15      208736
11        18      254242
12        20      243723
# todas as linhas de df1 ou df2
df1 |> full_join(df2)
Joining with `by = join_by(author)`
                  author cntry                                 inst_name
1      Graetzel, Michael   che  École Polytechnique Fédérale de Lausanne
2        Wang, Zhong Lin   chn               Chinese Academy of Sciences
3     Willett, Walter C.   usa Harvard T.H. Chan School of Public Health
4          Kresse, Georg   aut                          Universität Wien
5     Kessler, Ronald C.   usa                    Harvard Medical School
6          Friston, Karl   gbr                 University College London
7     Altman, Douglas G.   gbr                                      <NA>
8       McEwen, Bruce S.   usa                                      <NA>
9  Whitesides, George M.   usa      Harvard Faculty of Arts and Sciences
10        Witten, Edward   usa              Institute for Advanced Study
11      Barnes, Peter J.   gbr                                      <NA>
12       Perdew, John P.   usa                                      <NA>
13      Halliwell, Barry   sgp          National University of Singapore
14          Ridker, Paul   usa                                      <NA>
15        Karin, Michael   usa           UC San Diego School of Medicine
16       Bandura, Albert   usa                                      <NA>
17     Semenza, Gregg L.   usa                                      <NA>
18          Yusuf, Salim   can                       McMaster University
19          Libby, Peter   usa                                      <NA>
20        Langer, Robert   usa     Massachusetts Institute of Technology
21         Akira, Shizuo  <NA>                          Osaka University
22        Folkman, Judah  <NA>                    Harvard Medical School
23   Goodenough, John B.  <NA>         The University of Texas at Austin
24        Grimme, Stefan  <NA>                          Universität Bonn
25          Hu, Frank B.  <NA>                    Harvard Medical School
26  Ioannidis, John P.A.  <NA>                       Stanford University
27       Jain, Rakesh K.  <NA>            Massachusetts General Hospital
28        Kroemer, Guido  <NA>                       Sorbonne Université
29       Trost, Barry M.  <NA>                       Stanford University
30          Wang, Joseph  <NA>       University of California, San Diego
31       Zadeh, Lotfi A.  <NA>        University of California, Berkeley
   rank (ns) nc9623 (ns)
1          1      365234
2          2      279327
3          3      346654
4          4      297085
5          5      267255
6          6      188600
7         NA          NA
8         NA          NA
9          9      244615
10        10      101514
11        NA          NA
12        NA          NA
13        13      113708
14        NA          NA
15        15      208736
16        NA          NA
17        NA          NA
18        18      254242
19        NA          NA
20        20      243723
21        25      273403
22        24      130951
23        36      122468
24        27      125623
25        26      222570
26        22      242211
27        29      145488
28        34      241541
29        37       80092
30        35      102177
31        28      126012

7.2 Junções com filtragem

As duas seguintes funções de filtragem filtram linhas de x com base na presença ou ausência de correspondências em y:

  • semi_join() retorna todas as linhas de x com uma correspondência em y.
  • anti_join() retorna todas as linhas de x sem uma correspondência em y.

Fonte: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf

Fonte: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf
# linhas de df1 que estão em df2
df1 |> semi_join(df2)
Joining with `by = join_by(author)`
                  author cntry
1      Graetzel, Michael   che
2        Wang, Zhong Lin   chn
3     Willett, Walter C.   usa
4          Kresse, Georg   aut
5     Kessler, Ronald C.   usa
6          Friston, Karl   gbr
7  Whitesides, George M.   usa
8         Witten, Edward   usa
9       Halliwell, Barry   sgp
10        Karin, Michael   usa
11          Yusuf, Salim   can
12        Langer, Robert   usa
# linhas de df1 que NÃO estão em df2
df1 |> anti_join(df2)
Joining with `by = join_by(author)`
              author cntry
1 Altman, Douglas G.   gbr
2   McEwen, Bruce S.   usa
3   Barnes, Peter J.   gbr
4    Perdew, John P.   usa
5       Ridker, Paul   usa
6    Bandura, Albert   usa
7  Semenza, Gregg L.   usa
8       Libby, Peter   usa